/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package epibot.WebRobots;

import epibot.EstruturasBiologicas.Epitopo;
import epibot.EstruturasBiologicas.Proteina;
import epibot.robot.Proxy.GereciadorDoProxy;
import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Rafael Tosta
 */
public class NETMHC {

    public static Proteina processCalibragem(String seq, String allele, String epi_len,
            String codProteina, String nomeSite) throws IOException {

        Proteina p = new Proteina(codProteina, nomeSite, allele, epi_len, 0); // só para armazenar a proteina e os epítopos

        if (allele.contains("H2-K")) {
            allele = allele.replace("H2", "H-2");//"H-2-Kd");
        }

        if (allele.contains("HLA-A") || allele.contains("HLA-B")) {
            allele = allele.substring(0, 7) + ":" + allele.substring(7, 9);
        }

        URL url = new URL("http://www.cbs.dtu.dk/cgi-bin/webface");

        String boundary = FormUtility.getBoundary();

        URLConnection http;
        Proxy proxy = GereciadorDoProxy.getConexao();

        if (proxy == null) {
            //System.out.println("sem proxy");
            http = url.openConnection();
        } else {
            // System.out.println("com proxy");
            http = url.openConnection(proxy);
        }

        http.setDoOutput(true);

        http.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
        OutputStream os = http.getOutputStream();

        FormUtility form = new FormUtility(os, boundary);
        form.add("configfile", "/usr/opt/www/pub/CBS/services/NetMHC-3.4/NetMHC.cf");
        form.add("SEQPASTE", seq);
        if (allele.contains("H-2")) {
            form.add("master", "8"); //para mouse (H-2)
        } else {
            if (allele.contains("HLA-A")) {
                form.add("master", "2");
            } else {
                form.add("master", "3");
            }
        }
        form.add("allele", allele);
        form.add("peplen", epi_len);
        form.add("sort", "on");
        form.complete();

        // Get the intermediate page
        InputStream is = http.getInputStream();
        //Extract the link to the result page
        ParseHTML parse = new ParseHTML(is);

        // Parse the page to extract the link to the result table
        //System.out.println(parse.getTag().toString());
        int ch;
        String value = "";
        HTMLTag tag;
        StringBuilder buffer = new StringBuilder();

        while ((ch = parse.read()) != -1) {
            //  System.out.print((char) ch);
            if (ch == 0) {
                tag = parse.getTag();
                if (tag.getName().equalsIgnoreCase("a")) {
                    value = tag.getAttributeValue("href");
                    break;
                }
            } else {
                buffer.append((char) ch);
            }
        }

        if (!value.contains("http://www.cbs.dtu.dk/")) {
            // System.out.println(codProteina + " -> " + value);
            return null;
        }

        if (value.equals("email:(null)")) {
            // System.out.println("value = email:(null)");
            return null;
        }
        /*
         * Before the result page there is a transition page in case of the
         * server keeps a long time to return the answer. This work like a GET
         * form.
         */
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        FormUtility form2 = new FormUtility(bos, null);
        form2.add("jobid", "netmhc," + value);
        form2.add("opt", "wait");
        form2.complete();

        URL url2 = new URL("http://www.cbs.dtu.dk/cgi-bin/webface?" + bos.toString());

        //InputStream is2 = url2.openStream();
        URLConnection openConnection;
        InputStream is2 = null;
        if (proxy == null) {
            //System.out.println("sem proxy");
            is2 = url2.openStream();
        } else {
            // System.out.println("com proxy");
            is2 = url2.openConnection(proxy).getInputStream();
        }

        form2.add("opt", "none");
        form2.complete();

        URL url3 = new URL("http://www.cbs.dtu.dk/cgi-bin/webface?" + bos.toString());
        //InputStream is3 = url3.openStream();
        InputStream is3 = null;
        if (proxy == null) {
            //System.out.println("sem proxy");
            is3 = url3.openStream();
        } else {
            // System.out.println("com proxy");
            is3 = url3.openConnection(proxy).getInputStream();
        }

        //System.out.println(codProteina + "-->" + value);
        //REQUISIÇÃO A PARTIR DO LINK TEMPORARIO EM VALUE
        String m = makeRequest(value);
        //   System.out.println(codProteina + " : " + value);
        int cont = 0;
        String contem = "pos    peptide      logscore affinity(nM) Bind Level    Protein Name     Allele";

        while (!m.contains(contem)) {

            m = makeRequest(value);
            // System.out.println("não tem");
            cont++;
            if (cont > 100) {
                return null;
            }
        }

        p = parser(p, m);

        is.close();
        is2.close();
        is3.close();
        return p;
    }

    private static Proteina parser(Proteina p, String m) {
        String[] s = m.split("\n");
        String linha;
        String contem = "pos    peptide      logscore affinity(nM) Bind Level    Protein Name     Allele";

        //obter a linha inicial
        int k = 0;
        linha = s[k];
        while (!linha.contains(contem)) {
            k++;
            linha = s[k];
        }
        k = k + 2;
        //linha = s[k];
        //System.out.println(linha);

        //obter linha final
        contem = "----------------------";
        int j = k;
        linha = s[j];
        while (!linha.contains(contem)) {
            j++;
            linha = s[j];
        }

        //linha = s[j];
        //System.out.println(linha);
        int numEp = 0, limite = 50;
        //extrai os epitopos
        String[] ep;
        int rank = 0;
        String scoreAnt = "";
        for (int i = k; i < j; i++) {

            ep = s[i].split(" ");
            // System.out.println(ep.length);

            String temp = "";

            for (int y = 0; y < ep.length; y++) {
                //System.out.println(ep[y]);
                if (!ep[y].equals("")) {
                    temp = temp + "," + ep[y];
                }
            }

            String[] spl = temp.split(",");
            String pos = spl[1];
            String epitope = spl[2];
            String score = spl[3];

            if (!score.equals(scoreAnt)) {
                rank++;
                scoreAnt = score;
            }
            //limita a quantidade de epítopos a ser armazenados
            if (numEp == limite) {
                break;
            }
            numEp++;
            
            // System.out.println(rank + "," + pos + "," + epitope + "," + score);
            p.addEpitopo(new Epitopo(epitope, Integer.parseInt(pos), Double.parseDouble(score), rank, p));
        }
        
        return p;
    }

    private static String makeRequest(String urlAddress) {
        HttpURLConnection con = null;
        URL url = null;
        String response = null;
        try {
            url = new URL(urlAddress);
            con = (HttpURLConnection) url.openConnection();
            con.connect();
            response = readStream(con.getInputStream());

        } catch (IOException e) {
            //debug("Make ex: "+e.getMessage());
        } finally {
            con.disconnect();
        }
        return response;
    }

    /*
     * Transforma a stream da requisição httpcliente
     * em uma string
     * */
    private static String readStream(InputStream in) {
        BufferedReader reader = null;
        StringBuilder builder = new StringBuilder();
        try {
            reader = new BufferedReader(new InputStreamReader(in));
            String line = null;
            while ((line = reader.readLine()) != null) {
                builder.append(line + "\n");
            }
        } catch (IOException e) {
            //S("Read ex: "+e.getMessage());
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return builder.toString();
    }
    
}
